package cn.lingyangwl.framework.tool.core.exception;

import cn.lingyangwl.framework.tool.core.StringUtils;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * Assertion utility class that assists in validating arguments.
 *
 * <p>Useful for identifying programmer errors early and clearly at runtime.
 *
 * <p>For example, if the contract of a public method states it does not
 * allow {@code null} arguments, {@code Assert} can be used to validate that
 * contract.
 * <p>
 * For example:
 *
 * <code>
 * Assert.notNull(clazz, "The class must not be null");
 * Assert.isTrue(i > 0, "The value must be greater than zero");
 * </code
 * <p>
 * This class is empowered by org.springframework.util.Assert
 *
 * @author shenguangyang
 */
public abstract class Assert {

    /**
     * Assert a boolean expression, throwing {@code BizException}
     * <p>
     * for example
     *
     * <pre class="code">Assert.isTrue(i != 0, errorCode.B_ORDER_illegalNumber, "The order number can not be zero");</pre>
     *
     * @param expression a boolean expression
     * @param errorCode
     * @param errMessage the exception message to use if the assertion fails
     * @throws BizException if expression is {@code false}
     */
    public static void isTrue(boolean expression, Integer errorCode, String errMessage) {
        if (!expression) {
            throw new BizException(errorCode, errMessage);
        }
    }

    public static void isTrue(boolean expression, String errMessage) {
        if (!expression) {
            throw new BizException(errMessage);
        }
    }

    public static void isTrue(boolean expression, String msgTpl, Object... msgParams) {
        if (!expression) {
            throw new BizException(msgTpl, msgParams);
        }
    }

    public static void isTrue(boolean expression, Supplier<String> messageSupplier) {
        if (!expression) {
            throw new BizException(messageSupplier.get());
        }
    }

    public static void isTrue(boolean expression, BaseException exception) {
        if (Objects.isNull(exception)) {
            isTrue(expression, "error");
            return;
        }
        if (!expression) {
            throw exception;
        }
    }

    /**
     * Assert a boolean expression, if expression is true, throwing {@code BizException}
     * <p>
     * for example
     *
     * <pre class="code">Assert.isFalse(i == 0, errorCode.B_ORDER_illegalNumber, "The order number can not be zero");</pre>
     * <p>
     * This is more intuitive than isTure.
     */
    public static void isFalse(boolean expression, Integer errorCode, String errMessage) {
        if (expression) {
            throw new BizException(errorCode, errMessage);
        }
    }

    public static void isFalse(boolean expression, BaseError baseError) {
        if (expression) {
            throw new BizException(baseError);
        }
    }

    public static void isFalse(boolean expression, String errMessage) {
        if (expression) {
            throw new BizException(errMessage);
        }
    }

    public static void isFalse(boolean expression, Supplier<String> messageSupplier) {
        if (expression) {
            throw new BizException(messageSupplier.get());
        }
    }

    public static void isFalse(boolean expression, BaseException baseException) {
        if (Objects.isNull(baseException)) {
            isFalse(expression, "error");
            return;
        }
        if (expression) {
            throw baseException;
        }
    }

    public static void notNull(Object object, Integer errorCode, String errMessage) {
        if (object == null) {
            throw new BizException(errorCode, errMessage);
        }
    }

    public static void notNull(Object object) {
        if (object == null) {
            throw new BizException("系统异常");
        }
    }

    public static void notNull(Object object, BaseException baseException) {
        if (Objects.isNull(object)) {
            if (Objects.isNull(baseException)) {
                throw new BizException("error");
            }
            throw baseException;
        }
    }

    public static void isNull(Object object, Integer errorCode, String errMessage) {
        if (object != null) {
            throw new BizException(errorCode, errMessage);
        }
    }

    public static void isNull(Object object, String msgTpl, Object... msgParams) {
        if (object != null) {
            throw new BizException(msgTpl, msgParams);
        }
    }

    public static void isNull(Object object, BaseException baseException) {
        if (Objects.isNull(baseException)) {
            throw new BizException("系统异常");
        }
        if (object != null) {
            throw baseException;
        }
    }


    public static void notNull(Object object, String errMessage) {
        if (object == null) {
            throw new BizException(errMessage);
        }
    }

    public static void notNull(Object object, Supplier<String> messageSupplier) {
        if (object == null) {
            throw new BizException(messageSupplier.get());
        }
    }

    public static void notEmpty(Collection<?> collection, Integer errorCode, String errMessage) {
        if (collection == null || collection.isEmpty()) {
            throw new BizException(errorCode, errMessage);
        }
    }

    public static void notEmpty(Collection<?> collection, BaseError baseError) {
        if (collection == null || collection.isEmpty()) {
            throw new BizException(baseError);
        }
    }

    public static void notEmpty(Collection<?> collection, BaseException baseException) {
        if (baseException == null) {
            notEmpty(collection, "error");
            return;
        }
        if (collection == null || collection.isEmpty()) {
            throw baseException;
        }
    }

    public static void notEmpty(String str, String errMessage) {
        if (str == null || StringUtils.isEmpty(str)) {
            throw new BizException(errMessage);
        }
    }

    public static void notEmpty(String str, BaseException baseException) {
        if (Objects.isNull(baseException)) {
            notEmpty(str, "error");
            return;
        }
        if (str == null || StringUtils.isEmpty(str)) {
            throw baseException;
        }
    }

    public static void notEmpty(Collection<?> collection, String errMessage) {
        if (collection == null || collection.isEmpty()) {
            throw new BizException(errMessage);
        }
    }

    public static void notEmpty(Map<?, ?> map, Integer errorCode, String errMessage) {
        if (map == null || map.isEmpty()) {
            throw new BizException(errorCode, errMessage);
        }
    }

    public static void notEmpty(Map<?, ?> map, BaseError baseError) {
        if (map == null || map.isEmpty()) {
            throw new BizException(baseError);
        }
    }

    public static void notEmpty(Map<?, ?> map, BaseException baseException) {
        if (Objects.isNull(baseException)) {
            notEmpty(map, "error");
            return;
        }
        if (map == null || map.isEmpty()) {
            throw baseException;
        }
    }

    public static void notEmpty(Map<?, ?> map, String errMessage) {
        if (map == null || map.isEmpty()) {
            throw new BizException(errMessage);
        }
    }
}
